package edu.cs.networkmonitor.application;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import edu.cs.networkmonitor.application.NetMonitorDriver.SCANTYPE;
import edu.cs.networkmonitor.devices.BaseSource;

public class MonitorBoard {
	private JFrame _UIFrame;
	private JTable monitorTable;
	private JTable portTable;
	private JTable ipTable;
	private JTable deviceTable;
	private JScrollPane monitorInterface;
	private NetMonitorDriver driver;
	private final int IMAGEHEIGHT = 16;
	private int initmonitorX = 20;
	
	public MonitorBoard() {
		Resources.loadResources();
		driver = new NetMonitorDriver();
		initialize();
	}

	private void initialize() {
		_UIFrame = new JFrame();
		_UIFrame.setVisible(true);
		_UIFrame.setMinimumSize(new Dimension(900, 600));
		_UIFrame.setTitle("NetMonitor");
		_UIFrame.setBounds(100, 100, 450, 300);
		_UIFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		_UIFrame.setIconImage(new ImageIcon(Resources.getTitleIcon()).getImage());
		final JTabbedPane scanInterface = new JTabbedPane(JTabbedPane.TOP);

		JMenuBar menuBar = new JMenuBar();
		_UIFrame.setJMenuBar(menuBar);

		JMenu mnFile = new JMenu("File");
		JMenu mnView = new JMenu("View");
		JMenu mnHelp = new JMenu("Help");
		menuBar.add(mnFile);
		menuBar.add(mnView);
		menuBar.add(mnHelp);
        JMenuItem mntmExit = new JMenuItem("Exit");
        mntmExit.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
                System.exit(0);
            }
        });
        JMenuItem mntmHelp = new JMenuItem("About");
        mntmHelp.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
            	JOptionPane.showMessageDialog(_UIFrame,"Created by : Jose Antony"
            			,"About", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        
        JMenuItem view1 = new JMenuItem("Port Scanner");
        view1.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
            	scanInterface.setSelectedIndex(0);
            }
        });
        
        JMenuItem view2 = new JMenuItem("IP Scanner");
        view2.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
            	scanInterface.setSelectedIndex(1);
            }
        });
        
        JMenuItem view3 = new JMenuItem("Device Scanner");
        view3.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
            	scanInterface.setSelectedIndex(2);
            }
        });
        mnHelp.add(mntmHelp);
        mnFile.add(mntmExit);
        mnView.add(view1);
        mnView.add(view2);
        mnView.add(view3);

		_UIFrame.getContentPane().setLayout(null);
		
		BufferedImage scanPicture = Resources.getLogo();
		JLabel scanpicLabel = new JLabel(new ImageIcon(scanPicture));
		scanpicLabel.setBounds(705, 0, 140, 50);
		_UIFrame.getContentPane().add(scanpicLabel);

		scanInterface.setBounds(10, 36, 864, 233);
		_UIFrame.getContentPane().add(scanInterface);

		initializePortTab(scanInterface);
		initializeIpTab(scanInterface);
		initializeDeviceTab(scanInterface);


		JLabel lblMonitorInterface = new JLabel("MONITOR");
		lblMonitorInterface.setBounds(10, 280, 88, 14);
		_UIFrame.getContentPane().add(lblMonitorInterface);

		monitorInterface = new JScrollPane();
		monitorInterface.setBorder(new LineBorder(UIManager
				.getColor("InternalFrame.activeBorderColor")));
		monitorInterface.setBounds(10, 300, 864, 220);
		_UIFrame.getContentPane().add(monitorInterface);
		monitorInterface.setLayout(null);
        final String[] columnNames = { "Source Name", "Description", "Email", "Frequency(/min)"};
		monitorTable = new JTable(new Object[0][0],columnNames);
		monitorTable.setBackground(UIManager.getColor("RadioButtonMenuItem.background"));
		JScrollPane scrollPane = new JScrollPane(monitorTable);
		scrollPane.setBounds(10, 11, 700, 198);
		monitorInterface.add(scrollPane);
	}

	private void initializePortTab(JTabbedPane scanInterface) {
		final JComponent portPanel = new JPanel();
		portPanel.setLayout(null);
		scanInterface.addTab("Port Scanner ", null, portPanel, "Port Scanner");
		
		final JTextField hostname = new JTextField();
		hostname.setBounds(11, 11, 100, 20);
		portPanel.add(hostname);
		hostname.setText("localhost");
		hostname.setColumns(10);
		
		final JTextField frmPort = new JTextField();
		frmPort.setBounds(139, 11, 34, 20);
		portPanel.add(frmPort);
		frmPort.setColumns(10);

		JLabel lblTo = new JLabel("to");
		lblTo.setBounds(183, 14, 10, 14);
		portPanel.add(lblTo);

		final JTextField toPort = new JTextField();
		toPort.setBounds(203, 11, 34, 20);
		portPanel.add(toPort);
		toPort.setColumns(10);

		final JButton btnPortScan = new JButton("scan");
		btnPortScan.setBounds(265, 10, 89, 23);
		portPanel.add(btnPortScan);
		
		/*BufferedImage scanPic = Resources.getScanIcon();
		final JLabel scanLabel = new JLabel();
		scanLabel.setIcon(new ImageIcon("images/scan.gif"));
		scanLabel.setBounds(400, 5, scanPic.getWidth(), scanPic.getHeight());
		scanLabel.setVisible(false);
		portPanel.add(scanLabel);*/

        final String[] columnNames = { "Port", "Description"};

		btnPortScan.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent event) {
				String host = hostname.getText();
				String frm = frmPort.getText();
				String to = toPort.getText();
				if(frm == null || frm.isEmpty() || to == null || to.isEmpty()) {
					JOptionPane.showMessageDialog(_UIFrame,
							"Invalid range values.",
							"Input error", JOptionPane.ERROR_MESSAGE);
				} else {
					driver.scan(SCANTYPE.PORT, frm, to, host);
                    Object[][] driverData = driver.getColumnData(SCANTYPE.PORT); 
                    TableModel myModel = new DefaultTableModel(driverData, columnNames);
                    portTable.setModel(myModel);
                    int inity = 55;
                    if(driver.getPorts() != null) {
	            		for (int i = 0; i < driver.getPorts().size(); i++) {
	            				final int devi = i;
	            				BufferedImage myPicture = Resources.getAddIcon();
	            				JLabel picLabel = new JLabel(new ImageIcon(myPicture));
	            				picLabel.setBounds(550, inity+=IMAGEHEIGHT, myPicture.getWidth(), myPicture.getHeight());
	            				picLabel.setBorder(BorderFactory.createRaisedBevelBorder());
	            				picLabel.addMouseListener(new MouseAdapter() {
	
	            					@Override
	            					public void mouseClicked(MouseEvent event) {
	            							addToMonitorBorder(driver.getPorts().get(devi));
	        	            				String desc = portTable.getModel().getValueAt(devi, 1).toString();
	        	            				if(desc!=null)
	        	            					driver.getPorts().get(devi).setDescription(desc);
	            					}
	            				});
	            				portPanel.add(picLabel);
	            		}
                    }   
                    portPanel.repaint();
                    portPanel.revalidate();
                }
            }
            });
		
		portTable = new JTable(new Object[0][0], columnNames);
		portTable.setBackground(UIManager.getColor("Button.background"));
		JScrollPane scrollPane = new JScrollPane(portTable);
		scrollPane.setBackground(UIManager.getColor("Button.background"));
		scrollPane.setBounds(10, 45, 540, 150);
		portPanel.add(scrollPane);
		scanInterface.setMnemonicAt(0, KeyEvent.VK_1);
	}

    private void initializeIpTab(JTabbedPane scanInterface) {
    	final JComponent ipPanel = new JPanel();
        ipPanel.setLayout(null);
        scanInterface.addTab("IP Scanner", null, ipPanel, "IP Scanner");

        final JTextField frmIP = new JTextField();
        frmIP.setBounds(10, 11, 86, 20);
        ipPanel.add(frmIP);

        JLabel lblTo = new JLabel("to");
        lblTo.setBounds(106, 14, 10, 14);
        ipPanel.add(lblTo);

        final JTextField toIP = new JTextField();
        toIP.setBounds(122, 11, 86, 20);
        ipPanel.add(toIP);

        JButton btnIPScan = new JButton("scan");
        btnIPScan.setBounds(247, 10, 89, 23);
        ipPanel.add(btnIPScan);

        final String[] columnNames = { "IP Address", "Description"};

        btnIPScan.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent event) {
                String frm = frmIP.getText();
                String to = toIP.getText();
                if (frm == null || frm.isEmpty() || to == null || to.isEmpty()) {
                    JOptionPane.showMessageDialog(_UIFrame, "Invalid range values.",
                        "Input error", JOptionPane.ERROR_MESSAGE);
                }
                else {
                    driver.scan(SCANTYPE.IP, frm, to);
                    Object[][] driverData = driver.getColumnData(SCANTYPE.IP); 
                    TableModel myModel = new DefaultTableModel(driverData, columnNames);
                    ipTable.setModel(myModel);
                    int inity = 55;
                    if(driver.getIPS() != null) {
	            		for (int i = 0; i < driver.getIPS().size(); i++) {
	            				final int devi = i;
	            				BufferedImage myPicture = Resources.getAddIcon();
	            				JLabel picLabel = new JLabel(new ImageIcon(myPicture));
	            				picLabel.setBounds(550, inity+=IMAGEHEIGHT, myPicture.getWidth(), myPicture.getHeight());
	            				picLabel.setBorder(BorderFactory.createRaisedBevelBorder());
	            				picLabel.addMouseListener(new MouseAdapter() {
	
	            					@Override
	            					public void mouseClicked(MouseEvent event) {
	            							addToMonitorBorder(driver.getIPS().get(devi));
	        	            				String desc = ipTable.getModel().getValueAt(devi, 1).toString();
	        	            				if(desc!=null)
	        	            					driver.getIPS().get(devi).setDescription(desc);
	            					}
	            				});
	            				ipPanel.add(picLabel);
	            		}
                    }   
                    ipPanel.repaint();
                    ipPanel.revalidate();
                }
            }
            });

        ipTable = new JTable(new Object[0][0], columnNames);
        JScrollPane scrollPane = new JScrollPane(ipTable);
        scrollPane.setBounds(10, 45, 540, 150);
        ipPanel.add(scrollPane);
        scanInterface.setMnemonicAt(1, KeyEvent.VK_2);
    }

    private void initializeDeviceTab(JTabbedPane scanInterface) {
        JComponent devicePanel = new JPanel();
        devicePanel.setLayout(null);
        scanInterface.addTab("DeviceScanner", null, devicePanel, "Device Scanner");
        scanInterface.setMnemonicAt(2, KeyEvent.VK_3);

        JButton btnDevScan = new JButton("scan");
        btnDevScan.setBounds(10, 10, 89, 23);
        devicePanel.add(btnDevScan);
        final JScrollPane devPanel = new JScrollPane();
        final String[] columnNames = { "Device Name", "Description"};
        btnDevScan.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent event) {
                
                driver.scan(SCANTYPE.DEVICE, null, null);
                Object[][] driverData = driver.getColumnData(SCANTYPE.DEVICE); 
                TableModel myModel = new DefaultTableModel(driverData, columnNames);
                deviceTable.setModel(myModel);
                int inity = 7;
                if(driver.getDevices() != null) {
        		for (int i = 0; i < driver.getDevices().size(); i++) {
        				final int devi = i;
        				BufferedImage myPicture = Resources.getAddIcon();
        				JLabel picLabel = new JLabel(new ImageIcon(myPicture));
        				picLabel.setBounds(545, inity+=IMAGEHEIGHT, myPicture.getWidth(), myPicture.getHeight());
        				picLabel.setBorder(BorderFactory.createRaisedBevelBorder());
        				picLabel.addMouseListener(new MouseAdapter() {

        					@Override
        					public void mouseClicked(MouseEvent event) {
        							addToMonitorBorder(driver.getDevices().get(devi));
        	        				String desc = deviceTable.getModel().getValueAt(devi, 1).toString();
        	        				if(desc!=null)
        	        					driver.getDevices().get(devi).setDescription(desc);
        					}
        				});
        				devPanel.add(picLabel);
        		}
                }   
                devPanel.repaint();
                devPanel.revalidate();
            }
        });

        deviceTable = new JTable(new Object[0][0], columnNames);
        deviceTable.setBorder(null);
        devPanel.setBorder(null);
        devPanel.setLayout(null);
        devPanel.setBounds(10, 45, 640, 150);
        JScrollPane scrollPane = new JScrollPane(deviceTable);
        scrollPane.setBorder(null);
        scrollPane.setBounds(0, 0, 540, 150);
        devPanel.add(scrollPane);
        devicePanel.add(devPanel);
    }

    public void start() {
    }
    

	private void addToMonitorBorder(final BaseSource deviceSource) {
		driver.scheduleDevice(deviceSource);
		repaintMonitor();
	}
	
	public void updateMonitorSection() {
        final String[] columnNames = { "Source Name", "Email", "Frequency(/min)"};

        Object[][] monitorData = driver.getScheduledData(); 
        final TableModel myModel = new DefaultTableModel(monitorData, columnNames);
        SwingUtilities.invokeLater(new Runnable(){public void run(){
        	 monitorTable.setModel(myModel);
        }});
		monitorInterface.repaint();
		monitorInterface.revalidate();
	}
	
	public void repaintMonitor() {
		java.util.List<Component> comps = Arrays.asList(monitorInterface.getComponents());
		for(Component c : comps){
 		if(c instanceof JLabel){
				monitorInterface.remove(c);
			 }
		}
        final String[] columnNames = { "Source Name", "Email", "Frequency(/min)"};

        Object[][] monitorData = driver.getScheduledData(); 
        final TableModel myModel = new DefaultTableModel(monitorData, columnNames);
        SwingUtilities.invokeLater(new Runnable(){public void run(){
       	 monitorTable.setModel(myModel);
       }});
        
        java.util.List<BaseSource> sources = driver.getSources();
        if(sources != null) {
			int monitorX = initmonitorX;
        	for(int i=0; i < sources.size(); i++) {
				final int row = i;
        		final BaseSource source = sources.get(i);
        			BufferedImage statusPic = source.getStatus() ? Resources.getPassIcon() : Resources.getFailIcon();
        			JLabel statusLabel = new JLabel(new ImageIcon(statusPic));
        			statusLabel.setBounds(725, monitorX+=IMAGEHEIGHT, 16, 16);
        			statusLabel.setBorder(BorderFactory.createRaisedBevelBorder());
        			
        			final BufferedImage startPicture = driver.isSourceRunning(source) ? Resources.getGreenStartIcon() : Resources.getStartIcon();
        			final JLabel picLabel = new JLabel(new ImageIcon(startPicture));
        			picLabel.setBounds(755, monitorX, startPicture.getWidth(), startPicture.getHeight());
        			picLabel.setBorder(BorderFactory.createRaisedBevelBorder());
        			final MonitorBoard board = this;
        			picLabel.addMouseListener(new MouseAdapter() {

        				@Override
        				public void mouseClicked(MouseEvent event) {
        					boolean invalidentry = false;
        					Integer freq = 0;
        					try {
        						freq = Integer.parseInt((String)monitorTable.getModel().getValueAt(row, 2).toString());
        					} catch (NumberFormatException e){
        						invalidentry = true;
        					}
        					String emails = monitorTable.getModel().getValueAt(row, 1).toString();
        					if(invalidentry || freq == null || freq <=0){
        						JOptionPane.showMessageDialog(_UIFrame,
        								"Invalid frequency value.",
        								"Input error", JOptionPane.ERROR_MESSAGE);
        					} else {
        						source.setTime(freq);
        						source.setEmail(emails);
        						driver.startMonitor(source, board);
        						updateMonitorSection();
        					}
        				}
        			});
        			BufferedImage stopPicture = Resources.getStopIcon();
        			JLabel spicLabel = new JLabel(new ImageIcon(stopPicture));
        			spicLabel.setBounds(780, monitorX, stopPicture.getWidth(), stopPicture.getHeight());
        			//spicLabel.setBorder(BorderFactory.createRaisedBevelBorder());
        			spicLabel.addMouseListener(new MouseAdapter() {

        				@Override
        				public void mouseClicked(MouseEvent event) {
        					if(driver.isSourceRunning(source)){
        						picLabel.setIcon(new ImageIcon(Resources.getStartIcon()));
        					}
        					driver.stopMonitor(source);
        					updateMonitorSection();
        				}
        			});
        			BufferedImage removePicture = Resources.getRemoveIcon();
        			JLabel rpicLabel = new JLabel(new ImageIcon(removePicture));
        			rpicLabel.setBounds(800, monitorX, removePicture.getWidth(), removePicture.getHeight());
        			//rpicLabel.setBorder(BorderFactory.createRaisedBevelBorder());
        			rpicLabel.addMouseListener(new MouseAdapter() {

        				@Override
        				public void mouseClicked(MouseEvent event) {
        					driver.removeMonitor(source);
        					repaintMonitor();
        				}
        			});
           			monitorInterface.add(statusLabel);
        			monitorInterface.add(picLabel);
        			monitorInterface.add(spicLabel);
        			monitorInterface.add(rpicLabel);
        	}
        }
		monitorInterface.repaint();
	 	monitorInterface.revalidate();
		
		
	}
}
